package se480.tracker;

import java.util.List;

import org.apache.log4j.Logger;

import se480.tracker.TrackerConstants.TrackerEventGroup;
import se480.tracker.client.QueryClient;
import se480.tracker.client.UpdateClient;
import se480.tracker.event.EventFactory;
import se480.tracker.event.TrackerEvent;
import se480.tracker.service.RegistrationService;
import se480.tracker.util.EventFileReader;

/**
 * This is a simulation object that takes the input file events and hands
 * them to their respective update or query client to run through the system.
 * 
 * @author mmichalak
 *
 */
public class EventProxy {
	static Logger logger = Logger.getLogger(EventProxy.class.getName());
	
	UpdateClient updateClient = null;
	QueryClient queryClient = null;
	RegistrationService regSvc = null;
	
	/**
	 * This is the step that starts the simulation in motion
	 */
	public void readEvents() {
		// 1. Read file
		EventFileReader er = new EventFileReader();
		List<String> lines = er.readFile();
		
		// 2. For Each line, convert to event w/ Factory
		int eventNo = 0;
		for (String line : lines) {
			eventNo++;
			
			TrackerEvent ev = EventFactory.createEvent(line);
			int tick = ev.getTick();
			
			// Trigger checkpoint/state events
			if ( (tick % TrackerConstants.CHECKPOINT_PARTIAL_INTERVAL == 0) && (tick % TrackerConstants.CHECKPOINT_FULL_INTERVAL != 0) ) {
				// Dump partial checkpoint
				logger.debug("Tick=" + tick + ".  Dumping partial checkpoint");
				regSvc.executePartialCheckpoint();
			}
			else if (tick % TrackerConstants.CHECKPOINT_FULL_INTERVAL == 0) {
				// Write checkpoint to Persistent Storage
				logger.debug("Tick=" + tick + ".  Dumping checkpoint to Persisent Storage");
				regSvc.executeFullCheckpoint();
			}
			
			// 3. Determine event type and hand to approp client (or a failover event to Registration Service)
			if (ev.getEventGroup() == TrackerEventGroup.UPDATE) {
				updateClient.sendUpdate(ev);
			}
			else if (ev.getEventGroup() == TrackerEventGroup.QUERY) {
				queryClient.sendQuery(ev);
			}
			else if (ev.getEventGroup() == TrackerEventGroup.FAIL) {
				regSvc.failOver(ev);
			}
			logger.debug("Event No=" + eventNo + " Tick=" + tick + "   " + ev.getEventType() + "  Id=" + ev.getId());
		}

	}


	public UpdateClient getUpdateClient() {
		return updateClient;
	}


	public void setUpdateClient(UpdateClient updateClPrx) {
		this.updateClient = updateClPrx;
	}


	public QueryClient getQueryClient() {
		return queryClient;
	}


	public void setQueryClient(QueryClient queryClientPrx) {
		this.queryClient = queryClientPrx;
	}


	public RegistrationService getRegSvc() {
		return regSvc;
	}


	public void setRegSvc(RegistrationService regSvc) {
		this.regSvc = regSvc;
	}
}
